import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  BeforeInsert,
  BeforeUpdate,
} from 'typeorm'
import * as bcrypt from 'bcrypt'
import { ManyToMany, JoinTable } from 'typeorm'
import { Role } from 'src/modules/rbac/entities/role.entity'

/**
 * 用户实体
 * 用于存储用户基本信息、认证信息等
 */
@Entity('va_users')
export class User {
  /** 用户主键ID */
  @PrimaryGeneratedColumn()
  id: number

  /** 用户名 */
  @Column({ length: 100, unique: true })
  username: string

  /** 邮箱 */
  @Column({ length: 255, unique: true })
  email: string

  /** 密码（加密存储） */
  @Column({ length: 255, select: false })
  password: string

  /** 昵称 */
  @Column({ length: 100, nullable: true })
  nickname: string

  /** 头像 */
  @Column({ length: 500, nullable: true })
  avatar: string

  /** 手机号 */
  @Column({ length: 20, nullable: true })
  phone: string

  /** 状态（1: 启用, 0: 禁用） */
  @Column({ default: 1 })
  status: number

  /** 最后登录时间 */
  @Column({ type: 'datetime', nullable: true })
  lastLoginAt: Date

  /** 创建时间 */
  @CreateDateColumn()
  createdAt: Date

  /** 更新时间 */
  @UpdateDateColumn()
  updatedAt: Date

  /** 插入前加密密码 */
  @BeforeInsert()
  async hashPassword() {
    if (this.password) {
      this.password = await bcrypt.hash(this.password, 10)
    }
  }

  /** 更新前加密密码 */
  @BeforeUpdate()
  async updatePassword() {
    if (this.password && this.password.length < 60) {
      this.password = await bcrypt.hash(this.password, 10)
    }
  }

  /** 验证密码 */
  async validatePassword(password: string): Promise<boolean> {
    return bcrypt.compare(password, this.password)
  }

  /** 用户拥有的角色列表 */
  @ManyToMany(() => Role)
  @JoinTable({
    name: 'va_user_roles',
    joinColumn: { name: 'user_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'role_id', referencedColumnName: 'id' },
  })
  roles: Role[]
}
